home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / asm / alib11b.zip / CODE1.ZIP / DISKINFO / FDUMP.ASM < prev    next >
Assembly Source File  |  1994-10-04  |  9KB  |  338 lines

  1.     title    'DUMP --- Display File Contents'
  2.  
  3. ; DUMP --- a utility to display the contents of a file in hex
  4. ; and ASCII format.  Requires PC-DOS 2.0 or MS-DOS 2.0.
  5.  
  6. ; Used in the form:
  7. ; A>dump path\filename.ext  [ >device ]
  8. ; (item in square brackets is optional)
  9.  
  10. ; version 1.0    March 25, 1984
  11. ; Copyright (c) 1984 by Ray Duncan
  12. ; May be freely reproduced for non-commercial use.
  13.  
  14. cr    equ    0dh        ;ASCII carriage return
  15. lf    equ    0ah        ;ASCII line feed
  16. blank    equ    20h        ;ASCII space code
  17.  
  18. command equ    80h        ;buffer for command tail
  19.  
  20. blksize equ    128        ;size of input file records
  21.  
  22. output_handle equ 1        ;handle of standard output device
  23.                 ;(can be redirected)
  24. error_handle equ 2        ;handle of standard error device
  25.                 ;(not redirectable)
  26.  
  27. cseg    segment para public 'CODE'
  28.  
  29.     assume    cs:cseg,ds:data,es:data,ss:stack
  30.  
  31.  
  32. dump    proc    far        ;entry point from PC-DOS
  33.  
  34.     push    ds        ;save DS:0000 for final
  35.     xor    ax,ax        ;return to PC-DOS
  36.     push    ax
  37.     mov    ax,data     ;make our data segment
  38.     mov    es,ax        ;addressable via ES register.
  39.     mov    ah,30h        ;check version of PC-DOS.
  40.     int    21h
  41.     cmp    al,2
  42.     jae    dump1        ;proceed, DOS 2.0 or greater.
  43.     mov    dx,offset msg3    ;DOS 1.x --- print error message;
  44.     mov    ax,es        ;we must use the old PC-DOS
  45.     mov    ds,ax        ;string output function since
  46.     mov    ah,9        ;handles are not available in
  47.     int    21h        ;this version of PC-DOS.
  48.     ret
  49.  
  50. dump1:    call    get_filename    ;get path and file spec. for
  51.                 ;input file from command line tail.
  52.     mov    ax,es        ;set DS=ES for remainder
  53.     mov    ds,ax        ;of program.
  54.     jnc    dump2        ;jump, got acceptable name.
  55.     mov    dx,offset msg2    ;missing or illegal filespec,
  56.     mov    cx,msg2_length
  57.     jmp    dump9        ;print error message and exit.
  58.  
  59. dump2:    call    open_input    ;now try to open input file
  60.     jnc    dump3        ;jump,opened input ok
  61.     mov    dx,offset msg1    ;open of input file failed,
  62.     mov    cx,msg1_length
  63.     jmp    dump9        ;print error msg and exit.
  64.  
  65. dump3:    call    read_block    ;initialize input file buffer
  66.     jnc    dump4        ;jump,got a block
  67.     mov    dx,offset msg4    ;empty file,print error
  68.     mov    cx,msg4_length
  69.     jmp    dump9        ;message and exit
  70.  
  71.                 ;file successfully opened,
  72. dump4:                ;now convert and display it!
  73.     call    get_char    ;read 1 character from input.
  74.     jc    dump8        ;jump, end of file
  75.     inc    input_addr    ;update relative file position
  76.     or    bx,bx        ;is this 1st char of block?
  77.     jnz    dump5        ;no
  78.     call    print_heading
  79. dump5:    and    bx,0fh        ;is this first byte of 16?
  80.     jnz    dump6        ;no,jump
  81.     push    ax        ;save the byte
  82.     mov    di,offset output;convert relative file addr.
  83.     mov    ax,input_addr    ;for output string
  84.     call    conv_word
  85.     pop    ax
  86. dump6:                ;store ASCII version of character,
  87.                 ;if it is alphanumeric,
  88.     mov    di,offset outputb
  89.     add    di,bx        ;calculate output string address
  90.     mov    byte ptr [di],'.' ;if it is control character,
  91.     cmp    al,blank    ;just print a dot.
  92.     jb    dump7        ;jump, not alphanumeric.
  93.     cmp    al,7eh
  94.     ja    dump7        ;jump, not alphanumeric.
  95.     mov    [di],al     ;store ASCII character.
  96. dump7:                ;now convert binary byte
  97.                 ;to hex  ASCII equivalent.
  98.     push    bx        ;save offset 0-15 of this byte.
  99.                 ;calc. its position in
  100.                 ;output string.
  101.     mov    di,offset outputa
  102.     add    di,bx        ;base addr + (offset*3)
  103.     add    di,bx
  104.     add    di,bx
  105.     call    conv_byte    ;convert data byte to hex
  106.     pop    bx        ;restore byte offset
  107.     cmp    bx,0fh        ;16 bytes converted yet?
  108.     jne    dump4        ;no,get another byte
  109.     mov    dx,offset output
  110.     mov    cx,output_length
  111.     call    write_std    ;yes, print the line
  112.     jmp    dump4        ;get next char. from input file.
  113.  
  114. dump8:                ;end of file detected,
  115.     call    close_input    ;close input file.
  116.     ret            ;now return to PC-DOS.
  117.  
  118. dump9:                ;come here to print message
  119.                 ;on standard error device,
  120.     call    write_error    ;and return control to PC-DOS
  121.     ret
  122.  
  123. dump    endp
  124.  
  125.  
  126. get_filename proc near        ;process name of input file
  127.                 ;return Carry = 0 if successful
  128.                 ;return Carry = 1 if no filename
  129.                 ;DS:SI <- addr command line
  130.     mov    si,offset command
  131.                 ;ES:DI <- addr filespec buffer
  132.     mov    di,offset input_name
  133.     cld
  134.     lodsb            ;any command line present?
  135.     or    al,al        ;return error status if not.
  136.     jz    get_filename4
  137. get_filename1:            ;scan over leading blanks
  138.     lodsb            ;to file name.
  139.     cmp    al,cr        ;if we hit carriage return...
  140.     je    get_filename4    ;jump, name is missing
  141.     cmp    al,20h        ;is this a blank?
  142.     jz    get_filename1    ;if so keep scanning.
  143. get_filename2:            ;found first char of name,
  144.     stosb            ;move last char. to output
  145.                 ;file name buffer.
  146.     lodsb            ;check next character, found
  147.     cmp    al,cr        ;carriage return yet?
  148.     je    get_filename3    ;yes,exit with success code.
  149.     cmp    al,20h        ;is this a blank?
  150.     jne    get_filename2    ;if not keep moving chars.
  151. get_filename3:            ;exit with carry =0
  152.     clc            ;for success flag
  153.     ret
  154. get_filename4:            ;exit with carry =1
  155.     stc            ;for error flag
  156.     ret
  157. get_filename endp
  158.  
  159. open_input proc near        ;open input file
  160.                 ;DS:DX=addr filename
  161.     mov    dx,offset input_name
  162.     mov    al,0        ;AL=0 for read only
  163.     mov    ah,3dh        ;function 3dh=open
  164.     int    21h        ;handle returned in AX,
  165.     mov    input_handle,ax ;save it for later.
  166.     ret            ;CY is set if error
  167. open_input endp
  168.  
  169. close_input proc near        ;close input file
  170.     mov    bx,input_handle ;BX=handle
  171.     mov    ah,3eh
  172.     int    21h
  173.     ret
  174. close_input endp
  175.  
  176. get_char proc    near        ;get one character from input buffer
  177.                 ;return AL = char, BX = buffer offset
  178.                 ;return CY flag = 1 if end of file
  179.     mov    bx,input_ptr    ;is pointer at end of buffer?
  180.     cmp    bx,blksize
  181.     jne    get_char1    ;no,jump
  182.                 ;yes, buffer is exhausted,
  183.     mov    input_ptr,0
  184.     call    read_block    ;new block must be read from disk.
  185.     jnc    get_char    ;got block, start routine over.
  186.     ret            ;end of file detected
  187.                 ;so return CY flag = True.
  188. get_char1:            ;get data byte into AL,
  189.     mov    al,[input_buffer+bx]
  190.     inc    input_ptr    ;bump input buffer pointer.
  191.     clc            ;return CY flag =0 since
  192.     ret            ;not end of file.
  193. get_char endp
  194.  
  195.  
  196. read_block proc near        ;read block of data from input file.
  197.                 ;return CY flag = 0 if read ok.
  198.                 ;    CY flag = 1 if end of file.
  199.     mov    bx,input_handle ;request read from PC-DOS.
  200.     mov    cx,blksize
  201.     mov    dx,offset input_buffer
  202.     mov    ah,3fh
  203.     int    21h
  204.                 ;initialize pointers
  205.     inc    input_block
  206.     mov    input_ptr,0
  207.     or    ax,ax        ;was anything read in? (the OR
  208.                 ; incidentally turns off the CY flag)
  209.     jnz    read_block1    ;yes,jump
  210.     stc            ;no,end of file so return CY=True
  211. read_block1:
  212.     ret
  213. read_block endp
  214.  
  215. write_std proc    near        ;write string to standard output.
  216.                 ;call DX = addr of output string
  217.                 ;     CX = length of string
  218.     mov    bx,output_handle;BX=handle for standard list device.
  219.     mov    ah,40h        ;function 40h=write to device.
  220.     int    21h        ;request service from DOS.
  221.     ret
  222. write_std endp
  223.  
  224. write_error proc near        ;write string to standard error device.
  225.                 ;call DX = addr of output string
  226.                 ;     CX = length of string
  227.     mov    bx,error_handle ;BX=handle for standard error device.
  228.     mov    ah,40h        ;function 40h=write to device.
  229.     int    21h        ;request service from DOS.
  230.     ret
  231. write_error endp
  232.  
  233. print_heading proc near     ;print record number and heading
  234.     push    ax        ;for a block of data
  235.     push    bx        ;first save registers
  236.     mov    di,offset headinga
  237.     mov    ax,input_block
  238.     call    conv_word    ;convert record number to ASCII
  239.     mov    dx,offset heading
  240.     mov    cx,heading_length
  241.     call    write_std    ;now print heading
  242.     pop    bx        ;restore registers
  243.     pop    ax
  244.     ret            ;and exit
  245. print_heading endp
  246.  
  247. conv_word proc near        ;convert 16-bit binary word
  248.                 ; to hex ASCII
  249.                 ;call with AX=binary value
  250.                 ;       DI=addr to store string
  251.                 ;returns AX, DI, CX destroyed
  252.     push    ax
  253.     mov    al,ah
  254.     call    conv_byte    ;convert upper byte
  255.     pop    ax
  256.     call    conv_byte    ;convert lower byte
  257.     ret
  258. conv_word endp
  259.  
  260. conv_byte proc      near        ;convert binary byte to hex ASCII
  261.                 ;call with AL=binary value
  262.                 ;       DI=addr to store string
  263.                 ;returns   AX, DI, CX modified
  264.  
  265.     sub    ah,ah        ;clear upper byte
  266.     mov    cl,16
  267.     div    cl        ;divide binary data by 16
  268.     call    ascii        ;the quotient becomes the first
  269.     stosb            ;ASCII character
  270.     mov    al,ah
  271.     call    ascii        ;the remainder becomes the
  272.     stosb            ;second ASCII character
  273.     ret
  274. conv_byte endp
  275.  
  276. ascii    proc    near        ;convert bottom 4 bits in AL
  277.     add    al,'0'          ;into the hex ASCII character
  278.     cmp    al,'9'
  279.     jle    ascii2        ;jump if in range 0-9,
  280.     add    al,'A'-'9'-1    ;offset it to range A-F,
  281. ascii2: ret            ;return ASCII char. in AL.
  282. ascii    endp
  283.  
  284. cseg    ends
  285.  
  286.  
  287. data    segment para public 'DATA'
  288.  
  289. input_name    db    64 dup (0)    ;buffer for input filespec
  290.  
  291. input_handle    dw    0        ;token from PCDOS for input file.
  292.  
  293. input_ptr    dw    0        ;pointer to input deblocking buffer
  294.  
  295. input_addr    dw    -1        ;relative address in file
  296. input_block    dw    0        ;current 128 byte block number
  297.  
  298. output        db    'nnnn',blank,blank
  299. outputa     db    16 dup ('00',blank)
  300.         db    blank
  301. outputb     db    '0123456789ABCDEF',cr,lf
  302. output_length    equ    $-output
  303.  
  304. heading     db    cr,lf,'Record',blank
  305. headinga    db    'nnnn',blank,blank,cr,lf
  306.         db    7 dup (blank)
  307.         db    '0  1  2  3  4  5  6  7  '
  308.         db    '8  9  A  B  C  D  E  F',cr,lf
  309. heading_length    equ    $-heading
  310.  
  311. input_buffer    db    blksize dup (?) ;deblocking buffer for input file
  312.  
  313. msg1        db    cr,lf
  314.         db    'Cannot find input file.'
  315.         db    cr,lf
  316. msg1_length    equ    $-msg1
  317.  
  318. msg2        db    cr,lf
  319.         db    'Missing file name.'
  320.         db    cr,lf
  321. msg2_length    equ    $-msg2
  322.  
  323. msg3        db    cr,lf
  324.         db    'Requires PC-DOS version 2 or greater.'
  325.         db    cr,lf,'$'
  326.  
  327. msg4        db    cr,lf,'Empty file.',cr,lf
  328. msg4_length    equ    $-msg4
  329.  
  330. data    ends
  331.  
  332.  
  333. stack    segment para stack 'STACK'
  334.     db    64 dup (?)
  335. stack    ends
  336.  
  337.     end    dump
  338.